home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Devices / Apple Desktop Bus / ADB Key Spy 2 / ADBKS Driver.c < prev    next >
Encoding:
Text File  |  1996-01-11  |  3.8 KB  |  178 lines  |  [TEXT/R*ch]

  1.     //
  2.     //    from 'ADB Key Spy' • Pete Gontier • gurgle@apple.com
  3.     //    Macintosh Developer Technical Support
  4.     //    © 1995,1996 Apple Computer, Inc.
  5.     //
  6.     //    Changes:
  7.     //
  8.     //        when        who        what
  9.     //        --------------------------------------------------------------
  10.     //        01/11/96    PG        copied from another project,
  11.     //                            merged with various parts of old
  12.     //                            ADB Key Spy
  13.     //
  14.  
  15. #ifndef __DEVICES__
  16. #    include <Devices.h>
  17. #endif
  18.  
  19. #ifndef __A4STUFF__
  20. #    include <A4Stuff.h>
  21. #endif
  22.  
  23. #ifndef __SETUPA4__
  24. #    include <SetUpA4.h>
  25. #endif
  26.  
  27. #include "ADBKS Common.h"
  28. #include "ADBKS csCodes.h"
  29.  
  30. static tKeyboardInfo    *gKeyboardInfoList;
  31. static unsigned long    gOpenCount;
  32.  
  33. static pascal Boolean IsKeyDownAnywhere (unsigned char keyCode)
  34. {
  35.     //
  36.     //    Walks list of patched keyboards searching for one with the key
  37.     //    corresponding to the specified virtual key code held down.
  38.     //    Note this routine inspects arrays of virtual key codes
  39.     //    which were built elsewhere.
  40.     //
  41.  
  42.     if (keyCode <= kMaxKeyCode)
  43.     {
  44.         tKeyboardInfo *scan = gKeyboardInfoList;
  45.         while (scan)
  46.         {
  47.             if (scan->virtualKeyMap [keyCode] > 0)
  48.                 return true;
  49.     
  50.             scan = scan->next;
  51.         }
  52.     }
  53.  
  54.     return false;
  55. }
  56.  
  57. static pascal OSErr myOpen (ParmBlkPtr, DCtlPtr)
  58. {
  59.     //
  60.     //    We maintain a count of the number of times we have been
  61.     //    opened so that on closure we can bitch if we're closed
  62.     //    too many times. This is just to be defensive. We don't
  63.     //    really care whether we are open or closed.
  64.     //
  65.  
  66.     ++gOpenCount;
  67.     return noErr;
  68. }
  69.  
  70. static pascal OSErr myPrime (ParmBlkPtr, DCtlPtr)
  71. {
  72.     //
  73.     //    Silently does nothing in case somebody foolish decides to call it.
  74.     //
  75.  
  76.     return noErr;
  77. }
  78.  
  79. static pascal OSErr myControl (CntrlParamPtr pbp, DCtlPtr)
  80. {
  81.     //
  82.     //    Sets the (global) root of the list of patched keyboard records.
  83.     //    The list can only be set once to a non-nil value, presumably
  84.     //    by the extension which loaded this driver.
  85.     //
  86.  
  87.     OSErr result = controlErr;
  88.  
  89.     switch (pbp->csCode)
  90.     {
  91.         case kControlCode_SetKeyboardInfoList :
  92.  
  93. #if PARANOID
  94.             if (!gKeyboardInfoList)
  95.             {
  96. #endif
  97.                 gKeyboardInfoList = *((tKeyboardInfo **) (pbp->csParam));
  98.                 result = noErr;
  99. #if PARANOID
  100.             }
  101. #endif
  102.  
  103.             break;
  104.     }
  105.  
  106.     return result;
  107. }
  108.  
  109. static pascal OSErr myStatus (CntrlParamPtr pbp, DCtlPtr)
  110. {
  111.     //
  112.     //    Driver-level interface to IsKeyDownAnywhere.
  113.     //    On input, the first byte of csParam should be the virtual key code.
  114.     //    On output, the first byte of csParam is a boolean describing
  115.     //    whether the key is being held down.
  116.     //
  117.  
  118.     OSErr result = statusErr;
  119.  
  120.     switch (pbp->csCode)
  121.     {
  122.         case kStatusCode_IsKeyDownAnywhere :
  123.  
  124.             {
  125.                 unsigned char *csParam = (unsigned char *) pbp->csParam;
  126.                 *csParam = IsKeyDownAnywhere (*csParam);
  127.                 result = noErr;
  128.             }
  129.             break;
  130.     }
  131.  
  132.     return result;
  133. }
  134.  
  135. static pascal OSErr myClose (ParmBlkPtr, DCtlPtr)
  136. {
  137.     //
  138.     //    We maintain a count of the number of times we have been
  139.     //    opened so that on closure we can bitch if we're closed
  140.     //    too many times. This is just to be defensive. We don't
  141.     //    really care whether we are open or closed.
  142.     //
  143.  
  144.     if (!gOpenCount)
  145.         DebugStr ("\pPlease close .adb_key_spy only as many times as you open it.");
  146.     else
  147.         --gOpenCount;
  148.  
  149.     return noErr;
  150. }
  151.  
  152. OSErr main (ParmBlkPtr paramBlock, DCtlPtr devCtlEnt, short dispatch)
  153. {
  154.     //
  155.     //    This is just glue for the rest of the driver. Pathetic that
  156.     //    compilers must also provide glue which will only call this glue.
  157.     //    Oh well, the Device Manager works the way it works.
  158.     //
  159.  
  160.     OSErr err = noErr;
  161.  
  162.     long oldA4 = SetCurrentA4 ( );
  163.     RememberA4 ( );
  164.  
  165.     switch(dispatch)
  166.     {
  167.         case 0: err = myOpen    (paramBlock, devCtlEnt);                    break;
  168.         case 1: err = myPrime    (paramBlock, devCtlEnt);                    break;
  169.         case 2:    err = myControl    (&(paramBlock->cntrlParam), devCtlEnt);        break;
  170.         case 3: err = myStatus    (&(paramBlock->cntrlParam), devCtlEnt);        break;
  171.         case 4: err = myClose    (paramBlock, devCtlEnt);                    break;
  172.     }
  173.  
  174.     SetA4 (oldA4);
  175.  
  176.     return err;
  177. }
  178.